package dataManage

import (
	"db2s/global"
	"db2s/ref"
	"fmt"
	"strings"
	"time"
)

var (
	ObjectMode              = []string{"job", "view", "mview", "seq", "type", "trigger", "func", "foreign", "procedure", "package"}
	TableMode               = []string{"table"}
	ObjectAction            = []string{"Create", "Alter"}
	IndexObjectType         = []string{"Primary", "Unique", "Index", "MissIndex"}
	ColumnMaxTextTypeObject = []string{"Lob", "Text", "Normal"}
	HundredMap              = map[string]string{"Hundred": "10w", "OneMillion": "100w", "TenMillion": "1000w", "OneHundredMillion": "1y", "TenHundredMillion": "10y", "tenBillion": "100y"}
	TableRowsObject         = []string{"Hundred", "OneMillion", "TenMillion", "OneHundredMillion", "TenHundredMillion"}
)

type FileManageEr interface {
	InitBasePath() error
}
type configFileManage struct {
	fileName map[string]string
}
type DataManage struct {
	Name        string //task name  具有唯一性
	TimeStamp   time.Time
	BaseDir     string
	Run         string           `json:"run"`
	Config      configFileManage `json:"config"`
	DataDir     string           `json:"dataDir"`
	Mode        []string         `json:"mode"`
	DataBaseDir []string         //基础的数据目录   //
}

func NewDataManage(name string, baseDir string, mode []string) DataManage {
	return DataManage{
		Name:    name,
		BaseDir: baseDir, //run、data、config、
		Mode:    mode,
		Config: configFileManage{
			fileName: map[string]string{"task": "gc-task.cnf", "rows": "gc-rows.cnf", "sync": "gc-sync.cnf", "struct": "gc-struct.cnf", "object": "gc-object.cnf"},
		},
	}
}
func (dma *DataManage) getBaseDir() string {
	return dma.BaseDir
}
func (dma *DataManage) getConfigPath() (res []string) {
	for _, v := range dma.Mode {
		res = append(res, fmt.Sprintf("%v/%v/%v/%v", dma.BaseDir, "config", dma.Name, v))
	}
	return
}
func (dma *DataManage) getBreakPointPath() (res []string) {
	for _, v := range dma.Mode {
		res = append(res, fmt.Sprintf("%v/%v/%v/%v", dma.BaseDir, "breakPoint", dma.Name, v))
	}
	return
}
func (dma *DataManage) getRunPath() (res string) {
	res = fmt.Sprintf("%v/%v/%v", dma.BaseDir, "run", dma.Name)
	return
}
func (dma *DataManage) getConfigObjectPath() (res []string) {
	paths := dma.getConfigPath()
	if len(paths) == 0 {
		return
	}
	// 预计算object数组，避免在循环中重复计算
	var object []string
	for _, modeVal := range dma.Mode {
		switch modeVal {
		case "object":
			object = ObjectMode
		default:
			object = TableMode
		}
	}
	// 预分配结果切片容量
	totalLen := len(paths) * len(object)
	if totalLen > 0 {
		res = make([]string, 0, totalLen)
	}
	for _, v := range paths {
		for _, obj := range object {
			res = append(res, fmt.Sprintf("%v/%v/%v", v, "object", obj))
		}
	}
	return
}
func (dma *DataManage) initRowsDataObjectSubFile(mode string) (res []string) {
	for _, v := range IndexObjectType {
		for _, v1 := range TableRowsObject {
			for _, v2 := range ColumnMaxTextTypeObject {
				for _, role := range dma.GetConfigModeObjectNames(mode) {
					res = append(res, fmt.Sprintf("%v/%s_%s_%s", role, v, HundredMap[v1], v2))
				}
			}
		}
	}
	return
}
func (dma *DataManage) initStructObjectSubFile(mode string) (res []string) {
	for _, v := range ObjectAction {
		for _, role := range dma.GetConfigModeObjectNames(mode) {
			res = append(res, fmt.Sprintf("%v/%v", role, v))
		}
	}
	return
}
func (dma *DataManage) initManyObjectSubFile(mode string) (res []string) {
	for _, v := range ObjectAction {
		for _, role := range dma.GetConfigModeObjectNames(mode) {
			res = append(res, fmt.Sprintf("%v/%s", role, v))
		}
	}
	return
}

// GetConfigObjectFile 根据指定模式获取配置对象文件列表
// 参数:
//
//	mode - 操作模式，可选值为"sync"、"rows"、"struct"、"object"
//
// 返回值:
//
//	res - 配置对象文件路径列表
func (dma *DataManage) GetConfigObjectFile(mode string) (res []string) {
	switch mode {
	case "sync", "rows":
		return dma.initRowsDataObjectSubFile(mode)
	case "struct":
		return dma.initStructObjectSubFile(mode)
	case "object":
		return dma.initManyObjectSubFile(mode)
	default:
		return
	}
}
func (dma DataManage) GetConfigModeObjectNames(mode string) (res []string) {
	for _, v := range dma.getConfigObjectPath() {
		if strings.Contains(strings.ToLower(v), fmt.Sprintf("/%v/object", strings.ToLower(mode))) {
			res = append(res, v)
		}
	}
	return
}
func (dma *DataManage) GetRunFileNames(name string) (res string) {
	switch name {
	case "breakPoint":
		return fmt.Sprintf("%v/%v", dma.getRunPath(), global.BreakPointFileName)
	case "ttyBar":
		return fmt.Sprintf("%v/%v.result", dma.getRunPath(), global.MonitorBarFinishFileName)
	case "parameter":
		return fmt.Sprintf("%v/%v", dma.getRunPath(), global.ParameterRecord)
	case "tPod":
		return fmt.Sprintf("%v/%v.data", dma.getRunPath(), global.MonitorBarFinishFileName)
	}
	return ""
}
func (dma *DataManage) GetConfigModeFileNames(mode string) (res string) {
	var path string
	for _, v := range dma.getConfigPath() {
		if strings.HasSuffix(strings.ToLower(v), strings.ToLower(strings.TrimSpace(mode))) {
			path = v
		}
	}
	for k, v := range dma.Config.fileName {
		if strings.EqualFold(k, strings.TrimSpace(mode)) {
			res = fmt.Sprintf("%v/%v", path, v)
			return
		}
	}
	return
}
func (dma *DataManage) initConfigPath() (err error) {
	var mkdirPath []string
	mkdirPath = append(mkdirPath, dma.getConfigPath()...)
	mkdirPath = append(mkdirPath, dma.getConfigObjectPath()...)
	mkdirPath = append(mkdirPath, dma.getRunPath())
	mkdirPath = append(mkdirPath, dma.getBreakPointPath()...)
	for _, v := range mkdirPath {
		if _, err = ref.ReconstructionPath(v); err != nil {
			return
		}
	}
	return
}
func (dma *DataManage) Init() error {
	return dma.initConfigPath()
}

func (dma *DataManage) getDataBaseDir() []string {
	return dma.DataBaseDir
}
func (dma *DataManage) InitBasePath() (err error) {
	//for _, v := range dma.BaseDir {
	//	if _, err = ref.ReconstructionPath(v); err != nil {
	//		return
	//	}
	//}
	return
}
